package thinkinjava1.ch14;

import java.applet.Applet;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/**
 * Created by BobbyGu on 2017/2/27.
 */
class TwoCounter2i extends Thread {
    private boolean started = false;
    private TextField
            t1 = new TextField(5),
            t2 = new TextField(5);
    private Label l =
            new Label("count1 == count2");
    private int count1 = 0, count2 = 0;

    public TwoCounter2i(Container c) {
        Panel p = new Panel();
        p.add(t1);
        p.add(t2);
        p.add(l);
        c.add(p);
    }

    public void start() {
        if (!started) {
            started = true;
            super.start();
        }
    }

    public void run() {
        while (true) {
            synchronized(this) {
                t1.setText(Integer.toString(count1++));
                t2.setText(Integer.toString(count2++));
            }
            try {
                sleep(500);
            } catch (InterruptedException e){}
        }
    }

    public synchronized void synchTest() {
        Sharing2i.incrementAccess();
        if (count1 != count2)
            l.setText("Unsynched");
    }
}

class Watcher2i extends Thread {
    private Sharing2i p;

    public Watcher2i(Sharing2i p) {
        this.p = p;
        start();
    }

    public void run() {
        while (true) {
            for (int i = 0; i < p.s.length; i++)
                p.s[i].synchTest();
            try {
                sleep(500);
            } catch (InterruptedException e) {
            }
        }
    }
}

public class Sharing2i extends Applet {
    TwoCounter2i[] s;
    private static int accessCount = 0;
    private static TextField aCount =
            new TextField("0", 10);

    public static void incrementAccess() {
        accessCount++;
        aCount.setText(Integer.toString(accessCount));
    }

    private Button
            start = new Button("Start"),
            observer = new Button("Observe");
    private boolean isApplet = true;
    private int numCounters = 0;
    private int numObservers = 0;

    public void init() {
        if (isApplet) {
            numCounters =
                    Integer.parseInt(getParameter("size"));
            numObservers =
                    Integer.parseInt(
                            getParameter("observers"));
        }
        s = new TwoCounter2i[numCounters];
        for (int i = 0; i < s.length; i++)
            s[i] = new TwoCounter2i(this);
        Panel p = new Panel();
        start.addActionListener(new StartL());
        p.add(start);
        observer.addActionListener(new ObserverL());
        p.add(observer);
        p.add(new Label("Access Count"));
        p.add(aCount);
        add(p);
    }

    class StartL implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            for (int i = 0; i < s.length; i++)
                s[i].start();
        }
    }

    class ObserverL implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            for (int i = 0; i < numObservers; i++)
                new Watcher2i(Sharing2i.this);
        }
    }

    public static void main(String[] args) {
        Sharing2i applet = new Sharing2i();
        // This isn't an applet, so set the flag and
        // produce the parameter values from args:
        applet.isApplet = false;
        applet.numCounters =
                (args.length == 0 ? 5 :
                        Integer.parseInt(args[0]));
        applet.numObservers =
                (args.length < 2 ? 5 :
                        Integer.parseInt(args[1]));
        Frame aFrame = new Frame("Sharing2i");
        aFrame.addWindowListener(
                new WindowAdapter() {
                    public void windowClosing(WindowEvent e) {
                        System.exit(0);
                    }
                });
        aFrame.add(applet, BorderLayout.CENTER);
        aFrame.setSize(350, applet.numCounters * 100);
        applet.init();
        applet.start();
        aFrame.setVisible(true);
    }
}
